package org.springframework.boot.autoconfigure.data.redis;

import com.autoconfigure.redis.properties.RedisConnectionProperties;
import com.lemon.constant.ConfigSwitchConstant;
import io.lettuce.core.RedisClient;
import io.lettuce.core.resource.DefaultClientResources;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.cache.CacheManagerCustomizers;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;

import java.net.UnknownHostException;

/**
 * @author lemon
 * @version 1.0
 * @description: 创建 Lettuce Redis 连接
 * @date Create by lemon on 2020-07-08 18:31
 */
@Configuration("lettuceCacheManagerFactory")
@ConditionalOnClass(RedisClient.class)
@ConditionalOnProperty(name = ConfigSwitchConstant.REDIS_CACHE_CONFIG_ENABLE, havingValue = ConfigSwitchConstant.REDIS_CACHE_CONFIG_ENABLE_DEFAULT, matchIfMissing = true)
public class LettuceCacheManagerFactory extends AbstractCacheManagerFactory {
    private final ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider;

    private final ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider;

    private final ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizersProvider;

    LettuceCacheManagerFactory(CacheManagerCustomizers customizerInvoker,
                                   ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
                                   ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider,
                                   ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizersProvider) {
        super(customizerInvoker);
        this.sentinelConfigurationProvider = sentinelConfigurationProvider;
        this.clusterConfigurationProvider = clusterConfigurationProvider;
        this.builderCustomizersProvider = builderCustomizersProvider;
    }

    @Bean(destroyMethod = "shutdown")
    public DefaultClientResources lettuceClientResources() {
        return DefaultClientResources.create();
    }

    /**
     * @param properties
     * @return org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
     * @description
     * @author lemon
     * @date 2020-07-08 21:42
     */
    @Override
    public LettuceConnectionFactory createConnectionFactory(RedisConnectionProperties properties)
            throws UnknownHostException {
        LettuceConnectionConfiguration lettuceConnectionConfiguration = new LettuceConnectionConfiguration(properties,
                this.sentinelConfigurationProvider, this.clusterConfigurationProvider, this.builderCustomizersProvider);
        return lettuceConnectionConfiguration.redisConnectionFactory(this.lettuceClientResources());
    }

    /**
     * @param properties
     * @return org.springframework.cache.CacheManager
     * @description 根据配置创建缓存管理器
     * @author lemon
     * @date 2020-07-09 08:23
     */
    @Override
    public CacheManager createCacheManager(RedisConnectionProperties properties) throws UnknownHostException {
        LettuceConnectionFactory redisConnectionFactory = this.createConnectionFactory(properties);
        return this.createCacheManager(redisConnectionFactory, properties);
    }
}
